package icselab.util;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Transmission extends Thread{
	static final int BUFFER_LEN = 2048;
	private String sUrl;
	private String dest;
	
	public Transmission(String sUrl,String dest){
		this.sUrl = sUrl;
		this.dest = dest;
	}
	
	public void run(){
        // Define httpURLConnection ,default is null
        HttpURLConnection hc = null;
        URL url = null;
        if(!sUrl.endsWith(".zip"))
        {
        	System.err.println("No zip file in the given URL");
        }
        String tempDir = "temp\\";
        File file = new File(tempDir);   
		file.mkdirs();  	
        String tempFileName = tempDir+sUrl.substring(sUrl.lastIndexOf("/"));
        System.out.print("start to download the package...");
        System.out.println(sUrl);
        
        long beginPos = 0;
        long fileLength = 0;
        int num = 0;
        boolean isFinish = false;
        boolean isFirst = true;
        while (!isFinish && num <= 3) {
            try {
                url = new URL(sUrl);
                hc = (HttpURLConnection) url.openConnection();
                // begin downloading from beginPos
                hc.setRequestProperty("User-Agent", "Java/1.4.2");
                hc.setRequestProperty("RANGE", "bytes="
                        + String.valueOf(beginPos) + "-");
                InputStream instream = hc.getInputStream();

                if (isFirst) {
                    fileLength = getFileLength(hc);
                    isFirst = false;
                }

                //Create a file output stream
                RandomAccessFile ras = new RandomAccessFile(tempFileName, "rw");
                ras.seek(beginPos);

                byte[] buf = new byte[BUFFER_LEN];
                int len = instream.read(buf, 0, BUFFER_LEN);
                while (len > 0){
                    beginPos += len;
                    ras.write(buf, 0, len);
                    len = instream.read(buf, 0, BUFFER_LEN);
                }
                ras.close();
                if (beginPos >= fileLength) {
                    isFinish = true;
                }         
            } catch (MalformedURLException e) {
            	System.out.println("MalformedURLException");
                System.err.println(e.getMessage());
            } catch (IOException e) {
            	System.out.println("IOException");
                System.err.println(e.getMessage());
            } finally {
                num++;
                hc.disconnect();
            }
        }       
        System.out.println("finished\n"+"start to unfold package...");
        extZipFileList(tempFileName, dest);
        System.out.println("finished\n");
    }

    /** *//**
     * get file length from HttpURLConnection, the HttpURLConnection's status is open
     * 
     * @param hc
     * @return long
     */
    private static long getFileLength(HttpURLConnection hc){
        long nFileLength = -1;
        for (int i = 1;; i++){
            String sHeader = hc.getHeaderFieldKey(i);
            if (sHeader != null){
                if (sHeader.equals("Content-Length")){
                    nFileLength = Long.parseLong(hc.getHeaderField(sHeader));
                    break;
                }
            } else{
                break;
            }
        }
        return nFileLength;
    }
    
    private static void extZipFileList(String zipFileName,String extPlace)
    {
    	boolean success = false;
    	try{   
    		  ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName));   
    		  ZipEntry entry = null;   
    		  while ((entry = zis.getNextEntry()) != null)   
    		  {   
    			  String entryName = entry.getName();   
    			  if(entryName.startsWith("appcode/") && entryName.length()>8)
    			  {
    				  entryName = entryName.substring(8);//delete appcode prefix
	    			  if(entry.isDirectory())
	    			  {   
	    				  File file = new File(extPlace + entryName);   
	    				  file.mkdirs();   
	    				  System.out.println("Create folder:" + entryName);   
	    			  }   
	    			  else
	    			  {   
	    				  FileOutputStream fos = new FileOutputStream(extPlace + entryName);    	    
	    				  //Transfer bytes from the ZIP file to the output file   
	    				  //BufferedOutputStream bof = new BufferedOutputStream(fos, BUFFER);
	    				  byte[] data = new byte[BUFFER_LEN];   
	    				  int len;   
	    				  while ((len = zis.read(data, 0, BUFFER_LEN))!= -1) 
	    				  {
	    					  fos.write(data, 0, len);
	    				  }
	    				  fos.flush();
	    				  fos.close();
	    			  }
	    			  zis.closeEntry(); 
	    			  success = true;
    			  }
    		  }
    	    }catch (IOException e)
    	    {
    	    	e.printStackTrace();
    	    }   
    	    if(success == false)
    	    	System.out.println("fail to decompress package file");   
    	    else
    	    	System.out.println("decompress package file successfully");   	    
    	  } 
}
